﻿// IWebWF
// Copyright (c) 2008
// by Michael Washington
// Webmaster@ADefWebserver.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
//
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.IO;
using System.Drawing;
using IWebWFCore;
using System.Xml;
using System.Collections.Specialized;
using System.Web.Configuration;
using System.Workflow.Runtime.Configuration;

namespace IWebWF
{
    public partial class SetupWizard : System.Web.UI.Page
    {
        string strCurrentVersion = "01.00.00";
        string[] arrSQLScriptsToRun = new string[] { "00.80.00.sql", "00.90.00.sql", 
            "00.90.01.sql", "00.90.02.sql", "00.90.03.sql", "00.90.04.sql", "00.90.05.sql", "00.90.06.sql", 
            "00.90.07.sql", "00.90.08.sql", "00.90.09.sql", "00.90.10.sql", "00.90.11.sql", "00.90.12.sql", 
            "00.90.13.sql", "00.90.14.sql", "00.90.15.sql", "00.90.16.sql", "00.90.17.sql", "01.00.00.sql" };

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                // If the site is already set-up do not allow the Install Wizard to run
                if (DatabaseReady())
                {
                    Response.Redirect("Default.aspx");
                    Response.End();
                }
            }
        }

        #region Navigation
        protected void btnWelcomeNext_Click(object sender, EventArgs e)
        {
            blPermissions.Items.Clear();

            if (!IsUpgrade())
            {
                mvSetupWizard.SetActiveView(vwPermissions);
            }
            else
            {
                // This is an upgrade so run .sql scripts
                mvSetupWizard.SetActiveView(vwDatabaseSetup);
                SetupDatabase();
            }
        }

        protected void btnPermissionsPrevious_Click(object sender, EventArgs e)
        {
            mvSetupWizard.SetActiveView(vwWelcome);
        }

        protected void btnPermissionsNext_Click(object sender, EventArgs e)
        {
            mvSetupWizard.SetActiveView(vwDatabaseSetup);
            SetupDatabase();
        }

        protected void btnDatabasePrevious_Click(object sender, EventArgs e)
        {
            blPermissions.Items.Clear();
            mvSetupWizard.SetActiveView(vwPermissions);
        }

        protected void btnDatabaseNext_Click(object sender, EventArgs e)
        {
            mvSetupWizard.SetActiveView(vwDatabaseSetup);
            SetupDatabase();
        }

        protected void btnCompletePrevious_Click(object sender, EventArgs e)
        {
            mvSetupWizard.SetActiveView(vwPermissions);
        }

        protected void btnAdministratorPrevious_Click(object sender, EventArgs e)
        {
            mvSetupWizard.SetActiveView(vwDatabaseSetup);
            SetupDatabase();
        }
        #endregion

        #region PermissionCheck
        protected void btnCheckPermissions_Click(object sender, EventArgs e)
        {
            int intValidItems = 0;
            blPermissions.Items.Clear();

            //FolderCreate
            ListItem permissionItem = new ListItem();
            permissionItem.Text = String.Format("Folder Create - {0}", ((VerifyFolderCreate()) ? "Passed" : "Failed"));
            permissionItem.Enabled = ((permissionItem.Text.Contains("Passed")) ? true : false);
            blPermissions.Items.Add(permissionItem);
            intValidItems = intValidItems + ((permissionItem.Text.Contains("Passed")) ? 1 : 0);

            //FileCreate
            permissionItem = new ListItem();
            permissionItem.Text = String.Format("File Create - {0}", ((VerifyFolderCreate()) ? "Passed" : "Failed"));
            permissionItem.Enabled = ((permissionItem.Text.Contains("Passed")) ? true : false);
            blPermissions.Items.Add(permissionItem);
            intValidItems = intValidItems + ((permissionItem.Text.Contains("Passed")) ? 1 : 0);

            //FileDelete
            permissionItem = new ListItem();
            permissionItem.Text = String.Format("File Delete - {0}", ((VerifyFolderCreate()) ? "Passed" : "Failed"));
            permissionItem.Enabled = ((permissionItem.Text.Contains("Passed")) ? true : false);
            blPermissions.Items.Add(permissionItem);
            intValidItems = intValidItems + ((permissionItem.Text.Contains("Passed")) ? 1 : 0);

            //FolderDelete
            permissionItem = new ListItem();
            permissionItem.Text = String.Format("Folder Delete - {0}", ((VerifyFolderCreate()) ? "Passed" : "Failed"));
            permissionItem.Enabled = ((permissionItem.Text.Contains("Passed")) ? true : false);
            blPermissions.Items.Add(permissionItem);
            intValidItems = intValidItems + ((permissionItem.Text.Contains("Passed")) ? 1 : 0);

            lblPermissionCheck.Text = String.Format("Permissions {0}", ((intValidItems == 4) ? "Passed" : "Failed"));
            lblPermissionCheck.BackColor = ((intValidItems == 4) ? Color.Green : Color.Red);

            // Show the Continue button?
            btnPermissionsNext.Visible = ((intValidItems == 4) ? true : false);
        }

        #region VerifyFolderCreate
        private bool VerifyFolderCreate()
        {
            string verifyPath = Server.MapPath("~/Verify");
            bool verified = true;

            //Attempt to create the Directory
            try
            {
                if (Directory.Exists(verifyPath))
                {
                    Directory.Delete(verifyPath, true);
                }

                Directory.CreateDirectory(verifyPath);
            }
            catch (Exception ex)
            {
                string strTemp = ex.Message;
                verified = false;
            }

            return verified;
        }
        #endregion

        #region VerifyFolderDelete
        private bool VerifyFolderDelete()
        {
            string verifyPath = Server.MapPath("~/Verify");
            bool verified = VerifyFolderCreate();

            if (verified)
            {
                //Attempt to delete the Directory
                try
                {
                    Directory.Delete(verifyPath);
                }
                catch (Exception ex)
                {
                    string strTemp = ex.Message;
                    verified = false;
                }
            }

            return verified;
        }
        #endregion

        #region VerifyFileCreate
        private bool VerifyFileCreate()
        {
            string verifyPath = Server.MapPath("~/Verify/Verify.txt");
            bool verified = VerifyFolderCreate();

            if (verified)
            {
                //Attempt to create the File
                try
                {
                    if (File.Exists(verifyPath))
                    {
                        File.Delete(verifyPath);
                    }

                    Stream fileStream = File.Create(verifyPath);
                    fileStream.Close();
                }

                catch (Exception ex)
                {
                    string strTemp = ex.Message;
                    verified = false;
                }
            }

            return verified;
        }
        #endregion

        #region VerifyFileDelete
        private bool VerifyFileDelete()
        {
            string verifyPath = Server.MapPath("~/Verify/Verify.txt");
            bool verified = VerifyFileCreate();

            if (verified)
            {
                //Attempt to delete the File
                try
                {
                    File.Delete(verifyPath);
                }
                catch (Exception ex)
                {
                    string strTemp = ex.Message;
                    verified = false;
                }
            }

            return verified;
        }
        #endregion

        #endregion

        #region FixWebConfig
        private void FixWebConfig()
        {
            // Updating the web.config removes parameters freom services. 
            // Replace them
            System.Configuration.Configuration rootWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
            WorkflowRuntimeSection WorkflowRuntimeSection = (WorkflowRuntimeSection)rootWebConfig.GetSection("WorkflowRuntime");
            string strWebConfig = WorkflowRuntimeSection.SectionInformation.GetRawXml();
            strWebConfig = strWebConfig.Replace("System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\"",
                "System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\" UseActiveTimers=\"true\"");
            strWebConfig = strWebConfig.Replace("System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\"",
                "System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\" UnloadOnIdle=\"true\" LoadIntervalSeconds=\"5\"");
            WorkflowRuntimeSection.SectionInformation.SetRawXml(strWebConfig);
            rootWebConfig.Save();
        } 
        #endregion

        #region Database Set-up
        private void SetupDatabase()
        {
            lblDatabaseSetup.Text = (DatabaseReady()) ? "The Database is already set-up. Click continue." : "Click the Continue button to run the database set-up scripts.";
        }

        private bool DatabaseReady()
        {
            // This method returns true if the database exists and the table is created
            bool CanConnect = true;            

            try
            {
                IWebWFDataContext IWebWFDataContext = new IWebWFDataContext();
                var result = from VersionNumber in IWebWFDataContext.Versions
                             select VersionNumber;
                CanConnect = (result.FirstOrDefault().VersionNumber == strCurrentVersion) ? true : false;
            }
            catch (Exception e)
            {
                string strError = e.Message;
                CanConnect = false;
            }

            return CanConnect;
        }

        private bool IsUpgrade()
        {
            // This method returns true if the databse exists and the table is created
            bool _IsUpgrade = true;
            int intCurrentVersion = Convert.ToInt32(strCurrentVersion.Replace(".", ""));
            try
            {
                IWebWFDataContext IWebWFDataContext = new IWebWFDataContext();
                var result = from VersionNumber in IWebWFDataContext.Versions
                             select VersionNumber;
                _IsUpgrade = (Convert.ToInt32(result.FirstOrDefault().VersionNumber.Replace(".", "")) < intCurrentVersion) ? true : false;
            }
            catch (Exception e)
            {
                string strError = e.Message;
                _IsUpgrade = false;
            }

            return _IsUpgrade;
        }

        protected void btnDatabaseSetupNext_Click(object sender, EventArgs e)
        {
            bool InUpgradeMode = IsUpgrade();

            if (!DatabaseReady())
            {
                try
                {
                    // Process all the SQL Scripts
                    foreach (string strSQLScript in arrSQLScriptsToRun)
                    {
                        string strSqlScript = GetSQLScript(strSQLScript);
                        IWebWFDataContext IWebWFDataContext = new IWebWFDataContext();
                        IWebWFDataContext.ExecuteCommand(strSqlScript);
                        // Log the event
                        ApplicationLog.AddToLog(String.Format("Processed upgrade script {0} ", strSQLScript));
                    }
                }
                catch (Exception ex)
                {
                    lblDatabaseSetup.Text = ex.Message;
                    return;
                }
            }

            if (!InUpgradeMode)
            {
                mvSetupWizard.SetActiveView(vwAdminAccount);
            }
            else
            {
                // This is an upgrade so go to end
                mvSetupWizard.SetActiveView(vwComplete);
            }

        }

        private String GetSQLScript(string strSQLScript)
        {
            string strSQL;
            string strFilePath = MapPath(String.Format(@"~/SQLScripts/{0}", strSQLScript));
            StreamReader reader = new StreamReader(strFilePath);
            strSQL = reader.ReadToEnd();
            reader.Close();
            reader = null;
            return strSQL;
        }
        #endregion

        #region Create Admin Account
        protected void btnCreateAdmin_Click(object sender, EventArgs e)
        {
            // Attempt to create the Administrator account
            if (txtUserName.Text.Trim() == "" | txtUserPassword.Text.Trim() == "" | txtUserEmail.Text.Trim() == "")
            {
                lblUserAccountResults.Text = "User name, password, and email must be entered to continue";
            }
            else
            {
                // Delete any SuperUser account
                IWebWFDataContext IWebWFDataContext = new IWebWFDataContext();
                var result = from Superusers in IWebWFDataContext.IWebWFUsers
                             where Superusers.UserName == "Superuser"
                             select Superusers;

                if (result.Count() > 0)
                {
                    IWebWFDataContext.IWebWFUsers.DeleteOnSubmit(result.FirstOrDefault());
                    IWebWFDataContext.SubmitChanges();
                }

                // Create SuperUser account
                IWebWFUser IWebWFUser = new IWebWFUser();

                IWebWFUser.Active = true;
                IWebWFUser.Email = txtUserEmail.Text.Trim();
                IWebWFUser.FirstName = "Super";
                IWebWFUser.LastName = "User";
                IWebWFUser.LoginFailures = 0;
                IWebWFUser.Password = txtUserPassword.Text.Trim();
                IWebWFUser.Role = "Administrators";
                IWebWFUser.SuperUser = true;
                IWebWFUser.UserName = txtUserName.Text.Trim();
                IWebWFUser.SilverlightKey = 0;

                IWebWFDataContext.IWebWFUsers.InsertOnSubmit(IWebWFUser);
                IWebWFDataContext.SubmitChanges();

                mvSetupWizard.SetActiveView(vwComplete);
            }
        }
        #endregion

        #region Complete
        protected void btnCompleteNext_Click(object sender, EventArgs e)
        {
            Response.Redirect("Default.aspx");
        }
        #endregion
    }
}